#!/usr/bin/ruby
#
# Simplebeat Copyright (C) 2007 Leroy van Logchem
#                               <leroy.vanlogchem@gmail.com>
#
# This file is part of Simplebeat
#
# Simplebeat is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# any later version.
#
# Simplebeat is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
#

# Lets add our library directory to Ruby's search path
$: << File.expand_path(File.dirname(__FILE__) + "/lib")

require 'thread'
require 'init.rb'

Syslog.info("-----------------------------------------------------")
Syslog.info("Simplebeat.failover starting")
Syslog.info("-----------------------------------------------------")

begin
#---------------------------------------------------------------
# Stonith (Shoot the other in the head)
#---------------------------------------------------------------
# The only reliable method. We want to be sure the resources are
# obtainable and exclusive to our node. Avoids:
#  - duplicate IP addresses
#  - locked drbd resources
#---------------------------------------------------------------
Syslog.info("Calling STONITH script to stop #{@remote_hosts.first}")
Syslog.info("#{@stonith_script}")
system("#{@stonith_script}")

#---------------------------------------------------------------
# Bring up aliased interfaces (virtual IP addresses)
#---------------------------------------------------------------
# Interfaces are configured using the regular files in:
# /etc/sysconfig/network-scripts/ifcfg-eth0:  <--- Only the :'s
# The RedHat centric 'ifup' script handles the arp updates
#---------------------------------------------------------------

Dir.glob "/etc/sysconfig/network-scripts/ifcfg-eth0:*" do |interface|
  ip = File.read(interface).to_a.detect {|l| l.match(/IPADDR/) }
  interface = File.basename(interface)
  Syslog.info("Started #{interface} : #{ip}")
  system("ifup #{interface}")
end

#---------------------------------------------------------------
# Make DRBD primary
#---------------------------------------------------------------

begin
  status = system("/sbin/drbdadm primary all")
  unless status
    Syslog.info("Tried drbd primary, not ok yet #{$?.exitstatus}.")
  end
  sleep 1
end until status

Syslog.info("Made all drbd resources primary")

#---------------------------------------------------------------
# Mount filesystems /dev/drbd* as configured in /etc/fstab
#
# A journal replay can take quite some time on TB filesystems.
# Heartbeat mounts them sequential, we do it parallel using threads
#---------------------------------------------------------------

mounts = File.read("/etc/fstab").grep(/#{@drbd_resource_prefix}/)
mounts.each { |mount|
  next unless mount.grep(/noauto/)
  Thread.new {
    Syslog.info("Mounting #{mount.split[0]} on #{mount.split[1]}")
    unless system("/bin/mount #{mount.split[1]}")
      Syslog.info("Mount #{mount.split[1]} failed: returncode : #{$?.exitstatus}!")
      Syslog.info("--> See man mount for details on the returncodes")
    end
    Thread.exit
  }
}

while Thread.list.size > 1
  Syslog.info("Waiting for mounting Threads to finish..")
  sleep 0.5
end
Syslog.info("Mounting finished")


#---------------------------------------------------------------
# Start our beloved services
#
# Scan /etc/init.d/ for files or symlinks with format:
# @service_prefix01thismuststartfirst
# @service_prefix02nowthis
# @service_prefix03asthirdthis
# and so on.
#---------------------------------------------------------------
services = Dir.glob "/etc/init.d/#{@service_prefix}*"
services.each { |s| services[services.index(s)] = File.basename(s) }
for i in 1..99 do
  # Prefix leading 0 to avoid trouble with more then 10 services
  i = sprintf("0%d",i) if i < 10
  service = services.select { |s| s.match(i.to_s) }
  next if service.empty?
  Syslog.info("Starting service: #{service} ")
  unless system("/sbin/service #{service} start")
    Syslog.info("Service #{service} failed: returncode : #{$?.exitstatus}!")
  end
end

ensure
  Syslog.info("-----------------------------------------------------")
  Syslog.info("Simplebeat.failover ends")
  Syslog.info("-----------------------------------------------------")
end

exec File.expand_path(File.dirname(__FILE__) + "/master.rb")
